﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Eneta.Portal.Common;
using Eneta.Portal.Common.Dto;
using Eneta.Portal.Common.Helpers;
using Eneta.Portal.Common.Repository;
using Eneta.Portal.Common.Services;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace Eneta.Portal.NewsAndBlogs.Controls
{
	public class AnnouncementControl : UserControl
	{
		protected HtmlAnchor profileLink;
		protected HtmlImage profileImage;
		protected HtmlAnchor authorLink;
		protected HtmlGenericControl publishDate;
		protected HtmlAnchor titleLink;
		protected HtmlGenericControl summaryField;
		protected HtmlGenericControl CommandButtons;
		protected HtmlGenericControl promoBox;
		protected HtmlGenericControl Body;
		protected PlaceHolder AddButtons;


		protected HtmlGenericControl ReadOnlyKeywordsContainer;
		protected Repeater ReadOnlyKeywordsRepeater;
		protected HtmlGenericControl CompanyContainer;
		protected HtmlAnchor CompanyLink;

		protected Label StatusLabel;
		protected HtmlGenericControl AcceptPostingContainer;
		protected Repeater keywordGroupsRepeater;
		protected TextBox rejectReasonField;
		protected Button ChangeEntry;
		protected Button AcceptEntry;
		protected Button RejectEntry;

		protected HtmlGenericControl CommentsCount;
		protected Repeater CommentsRepeater;
		protected HtmlGenericControl AddCommentContainer;
		protected HtmlAnchor AddCommentProfileLink;
		protected HtmlImage AddCommentProfileImage;

		protected TextBox CommentField;
		protected Button SubmitComment;

		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			ReadOnlyKeywordsRepeater.ItemDataBound += ReadOnlyKeywordsRepeaterItemDataBound;
			CommentsRepeater.ItemDataBound += CommentsRepeaterItemDataBound;
			SubmitComment.Click += SubmitCommentClick;
			ChangeEntry.Click += ChangeEntryClick;
			AcceptEntry.Click += AcceptEntryClick;
			RejectEntry.Click += RejectEntryClick;
			keywordGroupsRepeater.ItemDataBound += KeywordGroupsRepeaterItemDataBound;
		}

		private void ChangeEntryClick(object sender, EventArgs e)
		{
			Response.Redirect(EnetaApplication.PortalAnnouncementsEditPageUrl + "?aid=" + Announcement.Id + "&Owner=" + Announcement.OwnerProfileId);
		}

		protected void KeywordGroupsRepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
		{
			if (e.Item.DataItem == null)
				return;

			var groupName = (string)e.Item.DataItem;

			var groupNameLabel = (Label)e.Item.FindControl("groupNameLabel");
			groupNameLabel.Text = groupName;

			var keywordCheckList = (CheckBoxList)e.Item.FindControl("KeywordCheckList");

			var query = from k in GetAllKeywords()
						where k.GroupName == groupName
						orderby k.Title
						select k;
			keywordCheckList.DataSource = query;
			keywordCheckList.DataBind();

			foreach (ListItem item in keywordCheckList.Items)
			{
				var keywordId = int.Parse(item.Value);
				item.Selected = Announcement.Keywords.Exists(p => p.Id == keywordId);
			}
		}

		protected void ReadOnlyKeywordsRepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
		{
			if (e.Item.DataItem == null)
				return;

			var keyword = (Common.Dto.KeywordDto)e.Item.DataItem;
			var keywordLink = (HtmlGenericControl)e.Item.FindControl("KeywordLink");
			keywordLink.InnerText = keyword.Title;
		}

		protected void RejectEntryClick(object sender, EventArgs e)
		{
			AcceptItem(false);
			Response.Redirect(Request.RawUrl);
		}

		protected void AcceptEntryClick(object sender, EventArgs e)
		{
			AcceptItem(true);
			Response.Redirect(Request.RawUrl);
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			if(!string.IsNullOrEmpty(Request.QueryString["aid"]))
			{
				int aid;
				if(int.TryParse(Request.QueryString["aid"], out aid))
				{
					var rep = new AnnouncementRepository(EnetaApplication.PortalAnnouncementsSiteUrl);
					var ann = rep.GetAnnouncementById(aid);
					if (ann != null)
					{
						Response.Redirect(ann.DisplayUrl);
						return;
					}
				}
			}

			var user = SPContext.Current.Web.CurrentUser;            

			if (Announcement == null)
			{
				if (user != null)
					if (user.IsSiteAdmin)
						return;

				Response.Redirect(EnetaApplication.PortalAnnouncementsSiteUrl);
				return;
			}

			if (IsPostBack)
				return;

			Body.Visible = true;
			if (SPContext.Current.Web.CurrentUser != null)
			{
				if (AddButtons != null)
					AddButtons.Visible = true;
			}
			if (CommandButtons != null)
				CommandButtons.Visible = CurrentUserIsAdmin;
			var profileRepository = new UserProfileRepository(SPContext.Current.Web);
			var profile = profileRepository.GetUserProfileById(Announcement.OwnerProfileId);
			profileLink.HRef = EnetaApplication.PortalProfilePageUrl + "?profileID=" + profile.Id;
			profileImage.Src = profile.UserImage32x32Url; 
			authorLink.HRef = profileLink.HRef;
			authorLink.InnerText = Announcement.OwnerProfileName;
			publishDate.InnerText = Announcement.Created.ToShortDateString();
			titleLink.HRef = Announcement.DisplayUrl;
			titleLink.InnerText = Announcement.Title;
			summaryField.InnerHtml = RegExHelper.RemoveForbiddenAttributes(Announcement.Body);

			CommentsCount.InnerText = Announcement.Comments.Count.ToString();
			CommentsRepeater.DataSource = Announcement.Comments;
			CommentsRepeater.DataBind();

			AcceptPostingContainer.Visible = false;

			var currentUser = SPContext.Current.Web.CurrentUser;
			UserProfileDto profileItem = null;

			AddCommentContainer.Visible = false;
			if (currentUser != null)
			{
				profileItem = profileRepository.GetUserProfileByUserName(SPContext.Current.Web.CurrentUser.LoginName);
				if (profileItem != null)
				{
					AddCommentContainer.Visible = true;
				}
			}

			ReadOnlyKeywordsContainer.Visible = false;
			if (currentUser != null && currentUser.IsSiteAdmin)
			{
				AcceptPostingContainer.Visible = true;
				var query = from k in GetAllKeywords()
							orderby k.GroupName
							select k.GroupName;
				if (query.Count() > 0)
				{
					keywordGroupsRepeater.DataSource = query.Distinct();
					keywordGroupsRepeater.DataBind();
				}
				if (Announcement.Status == SPModerationStatusType.Approved)
                    StatusLabel.Text = GetResourceString("Approved");
				else if (Announcement.Status == SPModerationStatusType.Denied)
                    StatusLabel.Text = GetResourceString("Denied");
				else
                    StatusLabel.Text = GetResourceString("Pending");

			}
			else
			{
				ReadOnlyKeywordsContainer.Visible = true;
				ReadOnlyKeywordsRepeater.DataSource = Announcement.Keywords;
				ReadOnlyKeywordsRepeater.DataBind();
			}

			if (profileItem != null)
			{
				AddCommentContainer.Visible = true;
				AddCommentProfileLink.HRef = EnetaApplication.PortalProfilePageUrl + "?profileID=" + profileItem.Id;
				AddCommentProfileLink.Title = currentUser.Name;
				AddCommentProfileImage.Src = profile.UserImage32x32Url;
				AddCommentProfileImage.Alt = currentUser.Name;
			}

			if (Announcement.Companies != null)
				if (Announcement.Companies.Count > 0)
				{
					var company = Announcement.Companies[0];
					CompanyLink.HRef = company.DisplayUrl;
					CompanyLink.InnerText = company.Title;
				}

			if (string.IsNullOrEmpty(CompanyLink.HRef))
			{
				CompanyContainer.Visible = false;
			}

			ReadOnlyKeywordsContainer.Visible = (Announcement.Keywords.Count > 0);
		}

		private AnnouncementDto _announcement;

		protected AnnouncementDto Announcement
		{
			get
			{
				if (_announcement != null)
					return _announcement;

				_announcement = GetCurrentPost();
				return _announcement;
			}
		}

		protected void CommentsRepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
		{
			if (e.Item.DataItem == null)
				return;

			var comment = (CommentDto)e.Item.DataItem;
			var commentProfileLink = (HtmlAnchor)e.Item.FindControl("CommentProfileLink");
			var commentProfileImage = (HtmlImage)e.Item.FindControl("CommentProfileImage");
			var commentBody = (HtmlGenericControl)e.Item.FindControl("CommentBody");
			var commentProfileNameLink = (HtmlAnchor)e.Item.FindControl("CommentProfileNameLink");
			var commentTime = (HtmlGenericControl)e.Item.FindControl("CommentTime");

			var profileRepository = new UserProfileRepository(SPContext.Current.Web);
			var profile = profileRepository.GetUserProfileById(comment.OwnerProfileId);

			commentProfileLink.HRef = EnetaApplication.PortalProfilePageUrl + "?profileID=" + comment.OwnerProfileId;
			commentProfileLink.Title = comment.OwnerName;
			commentProfileImage.Src = profile.UserImage32x32Url;
			commentProfileImage.Alt = comment.OwnerName;

			commentBody.InnerHtml = RegExHelper.DetectAndReplaceUrls(comment.Body.Replace("\n", "<br/>"));
			commentProfileNameLink.HRef = commentProfileLink.HRef;
			commentProfileNameLink.Title = commentProfileLink.Title;
			commentProfileNameLink.InnerText = commentProfileLink.Title;
			commentTime.InnerText = comment.Created.ToString();
		}

		protected void SubmitCommentClick(object sender, EventArgs e)
		{
			var userName = SPContext.Current.Web.CurrentUser.LoginName;

			var dto = new CommentDto();
			dto.Body = CommentField.Text;
			dto.OwnerUserName = userName;
			dto.Parent = Announcement;

			var repository = new AnnouncementRepository(EnetaApplication.PortalAnnouncementsSiteUrl);
			repository.SaveComment(dto);

			Response.Redirect(Request.RawUrl, true);
		}

		private AnnouncementDto GetCurrentPost()
		{
			if (SPContext.Current.ListItem == null)
				return null;

			var id = SPContext.Current.ItemId;

			var repository = new AnnouncementRepository(EnetaApplication.PortalAnnouncementsSiteUrl);
			var currentUser = SPContext.Current.Web.CurrentUser;
			AnnouncementDto announcement;
			if (currentUser == null)
			{
				announcement = repository.GetPublicAnnouncementById(id);
			}
			else if (currentUser.IsSiteAdmin)
			{
				announcement = repository.GetAnnouncementById(id);
			}
			else
				announcement = repository.GetPublicAnnouncementById(id);

			return announcement;
		}

		private IList<KeywordDto> _allKeywords;
		private IList<KeywordDto> GetAllKeywords()
		{
			if (_allKeywords != null)
				return _allKeywords;

			_allKeywords = ClassificatorsRepository.GetAllKeywords();
			return _allKeywords;
		}

		private void AcceptItem(bool accept)
		{
			var announcementRepository = new AnnouncementRepository(EnetaApplication.PortalAnnouncementsSiteUrl);
			var dto = GetCurrentPost();

			var activity = new AdminActivityDto();
			activity.PreviousEditor = dto.OwnerUserName;
			activity.PreviousStatus = dto.Status;
			activity.PreviousTimeStamp = dto.Modified;
			activity.Module = "Announcements";
			activity.Url = Request.RawUrl;

			if (accept)
			{
				dto.Keywords.Clear();
				var keywords = new List<KeywordDto>();

				foreach (RepeaterItem groupItem in keywordGroupsRepeater.Items)
				{
					var checkList = (CheckBoxList)groupItem.FindControl("KeywordCheckList");
					if (checkList == null)
						continue;

					foreach (ListItem checkItem in checkList.Items)
					{
						if (!checkItem.Selected)
							continue;
								
						var keyword = new KeywordDto();
						keyword.Id = int.Parse(checkItem.Value);
						keyword.Title = checkItem.Text;                                                                
						dto.Keywords.Add(keyword);
					}
				}
				announcementRepository.SaveAnnouncement(dto);
			}

			if (accept)
			{
				if(activity.PreviousStatus != SPModerationStatusType.Approved)
				{
					/*var ownerValue = new SPFieldUserValue(web, item["RealAuthor"].ToString());
					var owner = ownerValue.User;
					var blogLink = "http://www.eneta.ee/uudised/teated/Lehed/" + item["FileLeafRef"];

					var mailer = new MailerService();
					var addresses = new[] { owner.Email, "abi@eneta.ee" };
					mailer.SendMailByTemplate("AnnouncementAccepted", owner.Name, item.Title, blogLink, addresses);
					*/
				}
				announcementRepository.ApproveAnnouncement(dto.Id, string.Empty);
				activity.CurrentStatus = SPModerationStatusType.Approved;
			}
			else
			{
				if (rejectReasonField != null)
				{
					announcementRepository.DenyAnnouncement(dto.Id, rejectReasonField.Text);
					activity.CurrentStatus = SPModerationStatusType.Denied;
				}
			}

			activity.CurrentEditor = SPContext.Current.Web.CurrentUser.LoginName;
			activity.CurrentTimeStamp = DateTime.Now;
			//ActivityLogger.LogActivity(activity);
		}

		private bool CurrentUserIsAdmin
		{
			get
			{
				var user = SPContext.Current.Web.CurrentUser;
				if (user == null)
					return false;

				return user.IsSiteAdmin;
			}
		}

		public static string GetUserProfileLink(HttpContext context)
		{
			var user = SPContext.Current.Web.CurrentUser;
			if (user == null)
				return string.Empty;

			var rep = new UserProfileRepository(SPContext.Current.Web);
			var profile = rep.GetUserProfileByUserName(user.LoginName);
			if (profile == null)
				return string.Empty;

			var profileLink = "<a href=\"profile.aspx?id=" + profile.Id + "\" title=\""+profile.UserName+"\">";
			profileLink += profile.UserName + "</a>";

			return profileLink;
		}

		public static string GetPromoBox(HttpContext context)
		{
			var user = SPContext.Current.Web.CurrentUser;
			if (user == null)
			{
				var output =
					@"<p><a href='/_layouts/Eneta.Portal.Authentication/LiveAuthHandler.aspx?action=login'>Logi sisse</a> ja lisa oma arvamus!</p>
					<p>Eneta portaali saad kasutada oma Live ID kontoga - see on sama, millega 
					suhtled Messengeris. Logi sisse, sest Enetas saad lisaks kommenteerimisele 
					<a href='/kommuun/eneta/Lehed/liikmed.aspx'>teha palju muud põnevat</a>.</p>";
				return output;
			}

			var rep = new UserProfileRepository(SPContext.Current.Web);
			var profile = rep.GetUserProfileByUserName(user.LoginName);
			if (profile == null)
				return string.Empty;

			var output2 = "<p>{0} <a href='/uudised/teated/AddAnnouncement.aspx'>kirjuta uudis</a> või <a href='/addblog.aspx'>lisa oma blogi</a>.</p>";
			output2 = string.Format(output2, profile.UserName);
			return output2;
		}
        private string GetResourceString(string label)
        {
            var resourceString = "$Resources:NewsAndBlogs," + label;
            var result = SPUtility.GetLocalizedString(resourceString, "NewsAndBlogs", SPContext.Current.Web.Language);
            return result;
        }
	}
}